package scala.test_object

import scala.annotation.tailrec

/**
 * @author 黄海峰 2021/4/16 10:16
 * */
object DeanTest {
  def main(args: Array[String]): Unit = {
    // function as parameters
    val salaries = Seq(2000, 4000, 3000)
    val doubleSalary = (x: Int) => x * 2
    println(salaries.map(doubleSalary))

    println(salaries.map(x => x * 3))

    println(salaries.map(_ * 4))
    println("====================>")

    // return a function as result
    val urlBuilderTest = new UrlBuilderTest
    val domainName = "www.jd.com"

    def getUrl: (String, String) => String = urlBuilderTest.urlBuilder(ssl = true, domainName)

    val endpoint = "users"
    val query = "id=1"
    println(getUrl(endpoint,query))
    println("====================>")

    // 递归
    def factorial(x: Int): Int = {
      @tailrec
      def fact(x: Int, accumulator: Int): Int = {
        if (x <= 1) accumulator
        else fact(x - 1, x * accumulator)
      }
      fact(x, 1)
    }

    println("Factorial of 2: " + factorial(2))
    println("Factorial of 3: " + factorial(3))
    println("Factorial of 3: " + factorial(5))
  }
}

/**
 * Higher order functions take other functions as parameters or return a function as a result.
 *
 * The only caveat is that you need to use _ in place of a parameter name
 *
 * An extractor object is an object with an <unapply> method.
 * Whereas the <apply> method is like a constructor which takes arguments and creates an object,
 * the unapply takes an object and tries to give back the arguments.
 * This is most often used in pattern matching and partial functions.
 *
 * 提取器对象是一个包含有unapply方法的单例对象。apply方法就像一个构造器，接受参数然后创建一个实例对象，反之unapply方法接受
 * 一个实例对象然后返回最初创建他的值。
 * 提取器常用再模式匹配和偏函数中。
 */